package logger

import (
	"fmt"
	"log"
	"os"
	"runtime"
	"strconv"
	"sync"
	"time"

	"auto/config"
)

var (
	infologger  *log.Logger
	debuglogger *log.Logger
	errorlogger *log.Logger
	logout      *os.File
	loglevel    int
	nowday      int

	fileLock sync.RWMutex
)

const (
	DebugLevel = iota // 0
	InfoLevel         // 1
	ErrorLevel        // 2
)

func init() {
	switch config.Conf.Logger.LogLevel {
	case DebugLevel:
		loglevel = DebugLevel
	case InfoLevel:
		loglevel = InfoLevel
	case ErrorLevel:
		loglevel = ErrorLevel
	}
	fileLock = sync.RWMutex{}
	SetFile()
}

func checkIfNowday() {
	var err error
	fileLock.Lock()
	defer fileLock.Unlock()
	day := time.Now().YearDay()
	if day == nowday {
		return
	} else {
		err = logout.Close()
		if err != nil {
			panic(err)
			return
		}
		yesterday := time.Now().Add(-24 * time.Hour).Format("20060102")
		err = os.Rename("log/log", "log/"+yesterday+".log")
		if err != nil {
			panic(err)
			return
		}
		SetFile()
		nowday = day
	}
}

// SetFile 初始化日志文件
func SetFile() {
	var err error
	logout, err = os.OpenFile("log/log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
	if err != nil {
		panic(err)
	} else {
		nowday = time.Now().YearDay() // 在一年里面是第几天
		infologger = log.New(logout, "[INFO] ", log.LstdFlags)
		debuglogger = log.New(logout, "[调试] ", log.LstdFlags)
		errorlogger = log.New(logout, "[ERROR] ", log.LstdFlags)
	}
}

// Info 打印INFO
func Info(format string, v ...any) {
	if loglevel <= DebugLevel {
		checkIfNowday()
		infologger.Printf(getPrefix()+format, v...)
	}
}

// Error 报错
func Error(format string, v ...any) {
	if loglevel <= ErrorLevel {
		checkIfNowday()
		errorlogger.Printf(getPrefix()+format, v...)
	}
}

// DebugPrint 调试打印
func DebugPrint(format string, v ...any) {
	fmt.Printf(format, v...)
	fmt.Println()
	if loglevel <= DebugLevel {
		checkIfNowday()
		debuglogger.Printf(getPrefix()+format, v...)
	}
}

func getCall() (string, int) {
	_, filename, line, ok := runtime.Caller(3)
	if ok {
		return filename, line
	} else {
		return "", 0
	}
}

func getPrefix() string {
	filename, line := getCall()
	return filename + ":" + strconv.Itoa(line) + "-->"
}
